Skip to content

CCCT-2440 Connect App Launch For Remaining Pages And Back Navigation#3756

Open
conroy-ricketts wants to merge 17 commits into
masterfrom
CCCT-2440-login-silent-launch-path-for-remaining-connect-pages
Open

CCCT-2440 Connect App Launch For Remaining Pages And Back Navigation#3756
conroy-ricketts wants to merge 17 commits into
masterfrom
CCCT-2440-login-silent-launch-path-for-remaining-connect-pages

Conversation

@conroy-ricketts

@conroy-ricketts conroy-ricketts commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

CCCT-2440

Stacked on top of CCCT-2439-connect-login-silent-launch-path — review/merge that first.

Product Description

Extends the no-login-screen Connect app launch to the remaining priority entry points and makes back navigation between the app and Connect consistent:

  • Launching a CommCare app from the Delivery Progress and Learning Progress pages now opens it directly (single loading dialog) instead of flashing the login and app-setup screens.
  • From a Connect-launched app's home screen, back returns to the Connect opportunities list (ending the app session).
  • Logging out from the app home now returns to the login screen (it previously dropped back onto the Connect page).
  • View Job Status on the app home opens the job's progress page on top of the live home; backing out of it returns to the app home, then back again returns to the opportunities list.
  • A job progress page opened directly from the opportunities list still backs out to the opportunities list.
Screen_Recording_20260609_113107_CommCare.Debug.mp4

Technical Summary

  • Extracts the launch/dialog/outcome-routing wiring that lived in ConnectJobsListsFragment into a shared ConnectAppLaunchController, and routes all three Connect launch surfaces (jobs list, delivery progress, learning progress) through it.
  • Home is launched for result: a back-out (RESULT_CANCELED) ends the app session and returns to the opportunities list; a logout (RESULT_OK) routes to the login screen through a reused DispatchActivity.
  • userPressedOpportunityStatus ("View Job Status") now launches the job-status page on top of the still-live home instead of finishing it, preserving back-to-home.
  • The progress dialog is driven by a small pure LaunchProgressMapperLaunchDialogState; dialog cleanup is handled by a view-lifecycle observer so callers don't manage it.
  • Removes dead code surfaced in review (the unused static HomeScreenBaseActivity.launchHome and ConnectAppUtils.getPasswordOverride/shouldOverridePassword).

Safety Assurance

Safety story

What gives confidence:

  • I ran the app and exercised the launch and back-navigation flows on a device.
  • The diff is scoped to the Connect launch surfaces; the shared controller centralizes logic that was previously duplicated.
  • LaunchProgressMapper, ConnectAppLauncher, and LaunchOutcomeRouter have JVM unit-test coverage.

Risks to review:

  • The multi-activity back-stack behavior (home ↔ job-status page ↔ opportunities list) is not exercised by the JVM test suite — it relies on the on-device verification above.
  • userPressedOpportunityStatus is shared with the legacy LoginActivity launch path; it now keeps home alive and launches the job page on top for that path too.
  • Removed ConnectAppUtils.getPasswordOverride/shouldOverridePassword after confirming no remaining source callers.

Automated test coverage

  • LaunchProgressMapperTest covers the per-phase dialog state mapping (seating / signing-in / syncing, percent handling, message override).
  • Existing ConnectAppLauncherTest and LaunchOutcomeRouterTest cover the launcher sequencing and outcome routing the controller delegates to.

conroy-ricketts and others added 6 commits June 8, 2026 15:28
[AI] Routed the delivery and learning progress fragments through the silent launch path by extracting the shared progress-dialog and outcome-routing wiring into ConnectAppLaunchUiController and delegating all three Connect launch surfaces to it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[AI] Addressed launch-controller review findings by injecting ConnectAppLauncher, extracting a pure LaunchProgressMapper with unit tests, self-dismissing the dialog via a view-lifecycle observer, and exposing named learn/delivery launch entrypoints.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[AI] Fixed the silent launch path dropping the "View Job Status" redirect by launching Home for result and routing REDIRECT_TO_CONNECT_OPPORTUNITY_INFO to the seated app's job status page, mirroring DispatchActivity's legacy handling.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[AI] Fixed Connect app back navigation so app Home backs out to the opportunities list (ending the app session) and "View Job Status" opens the job-status page on top of the live Home, preserving back-to-Home; reworked the prior for-result redirect handling accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[AI] Addressed review feedback: renamed ConnectAppLaunchUiController to ConnectAppLaunchController, drove the launch dialog from the full LaunchDialogState, removed dead code (the unused launchHome and password-override helpers), removed the "silent" wording, and tightened comments.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@conroy-ricketts conroy-ricketts self-assigned this Jun 9, 2026
@conroy-ricketts

Copy link
Copy Markdown
Contributor Author

Suggested Review Order

  • app/src/org/commcare/connect/ConnectAppLaunchController.kt — new shared launch orchestrator; the heart of the change
  • app/src/org/commcare/connect/ConnectNavHelper.kt — adds the clearTop option used by the back-out path
  • app/src/org/commcare/activities/HomeScreenBaseActivity.java — "View Job Status" + the Home launch intent; dead launchHome removed
  • app/src/org/commcare/fragments/connect/ConnectJobsListsFragment.java — refactored onto the shared controller (boilerplate removed)
  • app/src/org/commcare/fragments/connect/ConnectDeliveryProgressFragment.java — new caller of the controller
  • app/src/org/commcare/fragments/connect/ConnectLearningProgressFragment.java — new caller of the controller
  • app/src/org/commcare/connect/ConnectAppUtils.kt — dead-code removal
  • app/unit-tests/src/org/commcare/connect/LaunchProgressMapperTest.kt — dialog-state mapping tests
  • docs/commcare/login-engine.md — doc update for the launch/back-nav behavior
  • RELEASES.md — QA notes

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR refactors the Connect app launch flow by extracting repeated launch orchestration logic from multiple fragments into a shared ConnectAppLaunchController. The controller manages login-progress dialogs, maps login phases to UI states via LaunchProgressMapper, routes outcomes through LaunchOutcomeRouter (home launch, token handling, seat recovery, legacy fallback), logs analytics, and handles back navigation. HomeScreenBaseActivity is updated to navigate to seated-app job pages from the Opportunity Status action and provides a new buildHomeLaunchIntent() public API. Three Connect-progress fragments (ConnectJobsListsFragment, ConnectDeliveryProgressFragment, ConnectLearningProgressFragment) migrate from inline launch logic to controller delegation, removing ~150 lines of redundant code. Navigation utilities are enhanced (clearTop flag support) and unused password helpers are removed. Tests verify the mapper behavior; documentation describes the new flow and back-navigation semantics.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Suggested labels

skip-integration-tests

Suggested reviewers

  • OrangeAndGreen
  • shubham1g5
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'CCCT-2440 Connect App Launch For Remaining Pages And Back Navigation' clearly summarizes the main change: extending silent app launch and standardizing back navigation across Connect launch surfaces.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description comprehensively covers product changes, technical approach, and safety considerations with adequate detail and structure.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch CCCT-2440-login-silent-launch-path-for-remaining-connect-pages

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/org/commcare/activities/HomeScreenBaseActivity.java`:
- Around line 589-596: In userPressedOpportunityStatus() in
HomeScreenBaseActivity, handle the null case from
ConnectJobHelper.INSTANCE.getJobForSeatedApp(this) by adding user feedback
and/or logging: if job is null, call Android Toast (or Snackbar) to inform the
user (e.g., "No active job found") and add a process or Android log entry (Log.w
or your logger) noting that getJobForSeatedApp returned null; retain the
existing call to ConnectNavHelper.INSTANCE.goToActiveInfoForJob(this, job, true)
when job is non-null.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c93923c9-e88c-4f39-907f-e8e2e6d2f5c3

📥 Commits

Reviewing files that changed from the base of the PR and between aa9285c and ee1338f.

📒 Files selected for processing (10)
  • RELEASES.md
  • app/src/org/commcare/activities/HomeScreenBaseActivity.java
  • app/src/org/commcare/connect/ConnectAppLaunchController.kt
  • app/src/org/commcare/connect/ConnectAppUtils.kt
  • app/src/org/commcare/connect/ConnectNavHelper.kt
  • app/src/org/commcare/fragments/connect/ConnectDeliveryProgressFragment.java
  • app/src/org/commcare/fragments/connect/ConnectJobsListsFragment.java
  • app/src/org/commcare/fragments/connect/ConnectLearningProgressFragment.java
  • app/unit-tests/src/org/commcare/connect/LaunchProgressMapperTest.kt
  • docs/commcare/login-engine.md
💤 Files with no reviewable changes (1)
  • app/src/org/commcare/connect/ConnectAppUtils.kt

Comment thread app/src/org/commcare/activities/HomeScreenBaseActivity.java
@codecov

codecov Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 25.88%. Comparing base (cc723d3) to head (a82888a).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##             master    #3756   +/-   ##
=========================================
  Coverage     25.88%   25.88%           
+ Complexity     4388     4384    -4     
=========================================
  Files           949      950    +1     
  Lines         57129    57163   +34     
  Branches       6804     6811    +7     
=========================================
+ Hits          14786    14795    +9     
- Misses        40517    40538   +21     
- Partials       1826     1830    +4     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

conroy-ricketts and others added 2 commits June 9, 2026 11:48
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[AI] Logged a non-fatal workflow entry when "View Job Status" is pressed but no Connect job is found for the seated app, instead of silently doing nothing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@conroy-ricketts conroy-ricketts marked this pull request as ready for review June 9, 2026 15:54
…om:dimagi/commcare-android into CCCT-2440-login-silent-launch-path-for-remaining-connect-pages
…om:dimagi/commcare-android into CCCT-2440-login-silent-launch-path-for-remaining-connect-pages

@OrangeAndGreen OrangeAndGreen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed a couple behavioral changes with the new approach that I think we'll need to address.

  1. Back nav after launching app from learning/delivery progress pages
    Old behavior: navigating back from App Home (after successful login) returned to opportunity list
    New behavior: Back nav now returns to learning/delivery progress instead

  2. Logout button on App Home
    Old behavior: Logs out all the way to the Login page
    New behavior: Returns to previous page (opportunity list, learning/delivery progress, etc.)

…om:dimagi/commcare-android into CCCT-2440-login-silent-launch-path-for-remaining-connect-pages
@conroy-ricketts

Copy link
Copy Markdown
Contributor Author

@OrangeAndGreen

  1. Logout button on App Home

Great catch! I didn't think to test that

  1. Back nav after launching app from learning/delivery progress pages

I'm having trouble reproducing this point. Are you able to provide repro steps?

@OrangeAndGreen

OrangeAndGreen commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

No problem, these steps will show the different behavior:

  • In the opportunity list, press Resume on an opportunity in learning or one where delivery is complete (i.e. to navigate to the learning progress or delivery progress page instead of logging into the app directly)
  • On the learning or delivery progress page, press the Resume button to login in to the app
  • Swipe back on the App Home page (or press the back button if your device has one)

Results:

  • Master: Navigate back to opportunity list
  • This branch: Navigate back to learning/delivery progress page

@OrangeAndGreen

Copy link
Copy Markdown
Contributor

Did a pull on the latest code and the back nav is working as expected now, so only the Logout button behavior still to address.

conroy-ricketts and others added 2 commits June 11, 2026 16:12
[AI] Routed app-home logout to the login screen through a reused DispatchActivity (CLEAR_TOP | SINGLE_TOP) so it no longer drops back onto the Connect page or flashes a white screen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…om:dimagi/commcare-android into CCCT-2440-login-silent-launch-path-for-remaining-connect-pages
Base automatically changed from CCCT-2439-connect-login-silent-launch-path to master June 12, 2026 12:54
…-2440-login-silent-launch-path-for-remaining-connect-pages
// Launch the seated app's job status page on top of this (still-live) Home so the app
// session is preserved and backing out of the status page returns here.
ConnectJobRecord job = ConnectJobHelper.INSTANCE.getJobForSeatedApp(this);
if (job == null) {

@OrangeAndGreen OrangeAndGreen Jun 12, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocker: This seems crash-worthy to me, we should never show the Job Status button if not in a job context so the user clicking that button would indicate something is quite wrong.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great point

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private int initialTabPosition = 0;
private boolean isProgrammaticTabChange = false;
private ConnectDeliveryProgressViewModel viewModel;
private final ConnectAppLaunchController launchController = new ConnectAppLaunchController(this);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this could be a local variable in navigateToDeliverAppHome, or maybe use a static function instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for this not being a local variable or static is because ConnectAppLaunchController calls fragment.registerForActivityResult() when the fragment is initialized

So keeping it global here avoids an IllegalStateException crash (i.e. the fragment attempting to registerForActivityResult after being created)

);
launchDialog.addProgressBar();
if (isLearning) {
launchController.launchLearningApp(appId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Feels like we're splitting a boolean just to combine it back together, i.e. here we switch on isLearning to either call launchLearningApp or launchDeliveryApp, and those two functions just hard-code true and false for isLearning before calling launch(LaunchTarget(appId, isLearning)). A simple launchApp(appId, isLearning) seems like it would be more straight-forward.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I was a little torn about this at first, and looking back at it again I agree your suggestion is better

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onHomeResult(result)
}

fun launchLearningApp(appId: String) = launch(LaunchTarget(appId, isLearning = true))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Referenced in another comment but adding more detail here:
In all 3 usages of this class, we construct the class at fragment startup and then only use it in one place (technically two for he jobs list fragment but they're right next to each other and logically are like a single usage).

Is there a reason for the class to construct the launch controller before it's needed and hold a reference to it in the fragment? Otherwise I think a static launch method would be simpler and cleaner for callers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving convo to earlier thread here

conroy-ricketts and others added 2 commits June 12, 2026 11:50
[AI] Enforced a non-null job in userPressedOpportunityStatus via Objects.requireNonNull, since the Job Status button is only shown when a job exists for the seated app.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[AI] Replaced launchLearningApp/launchDeliveryApp with a single launchApp(appId, isLearning) on ConnectAppLaunchController and removed the boolean-splitting helper in ConnectJobsListsFragment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
[AI] Documented the logout (RESULT_OK) outcome routing to the login screen via a reused DispatchActivity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants